package routes

import (
	"tinyGW/app/api/schemas/req"
	"tinyGW/app/api/service"
	"tinyGW/app/api/types"
	"tinyGW/pkg/plugin/response"
	"tinyGW/pkg/service/http/middleware"
	"tinyGW/pkg/util"

	"github.com/gin-gonic/gin"
	"github.com/spf13/cast"
	"go.uber.org/fx"
)

type deviceType struct {
	fx.In
	Srv service.DeviceTypeService
}

func deviceTypeRouter(t deviceType, r *types.ApiRouter) {
	api := r.Group("/api", middleware.JWTAuth())
	api.POST("/device-type", t.add)
	api.PUT("/device-type", t.update)
	api.DELETE("/device-type/:name", t.delete)
	api.GET("/device-type/:name", t.find)
	api.GET("/device-types", t.findAll)
	api.GET("/device-type/list", t.list)
	api.POST("/device-type/upload/:name", t.upload)

	// id为设备类型id，propertyId为属性id
	api.POST("/device-property/:name", t.addProperties)
	api.PUT("/device-property/:name/:propertyid", t.updateProperties)
	api.DELETE("/device-property/:name/:propertyid", t.deleteProperties)
	api.GET("/device-property/:name/:propertyid", t.findProperty)
	api.GET("/device-property/:name", t.findAllProperties)

	// Lua 文件管理
	api.GET("/device-type/lua/:driver", t.getLuaFiles)             // 获取协议的所有文件
	api.GET("/device-type/lua/:driver/:filename", t.getLuaFile)    // 获取单个文件内容
	api.POST("/device-type/lua/:driver/:filename", t.saveLuaFile)  // 保存文件内容
	api.GET("/device-type/driver-usage/:driver", t.getDriverUsage) // 获取协议使用情况
	api.GET("/device-type/drivers", t.listDrivers)                 // 列出所有协议
	
	// 协议测试
	api.POST("/device-type/test-protocol/:driver", t.testProtocol) // 测试协议解析
}

func (t *deviceType) add(c *gin.Context) {
	var saveReq req.DeviceTypeReq
	if response.IsFailWithResp(c, util.VerifyUtil.Verify(c, &saveReq)) {
		return
	}
	err := t.Srv.Add(&saveReq)
	response.CheckAndResp(c, err)
}

func (t *deviceType) update(c *gin.Context) {
	var saveReq req.DeviceTypeReq
	if response.IsFailWithResp(c, util.VerifyUtil.Verify(c, &saveReq)) {
		return
	}
	err := t.Srv.Update(&saveReq)
	response.CheckAndResp(c, err)
}

func (t *deviceType) delete(c *gin.Context) {
	name := c.Param("name")
	if name == "" {
		response.FailWithMsg(c, response.ParamsValidError, "name不能为空")
		return
	}
	err := t.Srv.Delete(name)
	response.CheckAndResp(c, err)
}

func (t *deviceType) find(c *gin.Context) {
	name := c.Param("name")
	if name == "" {
		response.FailWithMsg(c, response.ParamsValidError, "name不能为空")
		return
	}
	res, err := t.Srv.Find(name)
	response.CheckAndRespWithData(c, res, err)
}

func (t *deviceType) findAll(c *gin.Context) {
	res, err := t.Srv.FindAll()
	response.CheckAndRespWithData(c, res, err)
}

func (t *deviceType) list(c *gin.Context) {
	var pageReq req.PageReq
	if response.IsFailWithResp(c, util.VerifyUtil.Verify(c, &pageReq)) {
		return
	}
	res, err := t.Srv.List(&pageReq)
	response.CheckAndRespWithData(c, res, err)
}

func (t *deviceType) addProperties(c *gin.Context) {
	name := c.Param("name")
	if name == "" {
		response.FailWithMsg(c, response.ParamsValidError, "name不能为空")
		return
	}
	var dpReq req.DeviceProperty
	if response.IsFailWithResp(c, util.VerifyUtil.Verify(c, &dpReq)) {
		return
	}
	err := t.Srv.AddProperties(name, &dpReq)
	response.CheckAndResp(c, err)
}

func (t *deviceType) updateProperties(c *gin.Context) {
	name := c.Param("name")
	if name == "" {
		response.FailWithMsg(c, response.ParamsValidError, "name不能为空")
		return
	}
	propertyId := c.Param("propertyid")
	if propertyId == "" {
		response.FailWithMsg(c, response.ParamsValidError, "propertyid不能为空")
		return
	}
	var dpReq req.DeviceProperty
	if response.IsFailWithResp(c, util.VerifyUtil.Verify(c, &dpReq)) {
		return
	}
	err := t.Srv.UpdateProperties(name, cast.ToInt(propertyId), &dpReq)
	response.CheckAndResp(c, err)
}

func (t *deviceType) deleteProperties(c *gin.Context) {
	name := c.Param("name")
	if name == "" {
		response.FailWithMsg(c, response.ParamsValidError, "name不能为空")
		return
	}
	propertyId := c.Param("propertyid")
	if propertyId == "" {
		response.FailWithMsg(c, response.ParamsValidError, "propertyid不能为空")
		return
	}
	err := t.Srv.DeleteProperties(name, cast.ToInt(propertyId))
	response.CheckAndResp(c, err)
}

func (t *deviceType) findProperty(c *gin.Context) {
	name := c.Param("name")
	if name == "" {
		response.FailWithMsg(c, response.ParamsValidError, "name不能为空")
		return
	}
	propertyId := c.Param("propertyid")
	if propertyId == "" {
		response.FailWithMsg(c, response.ParamsValidError, "propertyid不能为空")
		return
	}
	res, err := t.Srv.FindProperty(name, cast.ToInt(propertyId))
	response.CheckAndRespWithData(c, res, err)
}

func (t *deviceType) findAllProperties(c *gin.Context) {
	name := c.Param("name")
	if name == "" {
		response.FailWithMsg(c, response.ParamsValidError, "name不能为空")
		return
	}
	res, err := t.Srv.FindAllProperties(name)
	response.CheckAndRespWithData(c, res, err)
}

func (t *deviceType) upload(c *gin.Context) {
	name := c.Param("name")
	if name == "" {
		response.FailWithMsg(c, response.ParamsValidError, "name不能为空")
		return
	}

	res, err := t.Srv.Upload(name, c)
	response.CheckAndRespWithData(c, res, err)
}

func (t *deviceType) getLuaFiles(c *gin.Context) {
	driver := c.Param("driver")
	if driver == "" {
		response.FailWithMsg(c, response.ParamsValidError, "driver不能为空")
		return
	}

	res, err := t.Srv.GetLuaFiles(driver)
	response.CheckAndRespWithData(c, res, err)
}

func (t *deviceType) getLuaFile(c *gin.Context) {
	driver := c.Param("driver")
	filename := c.Param("filename")
	if driver == "" || filename == "" {
		response.FailWithMsg(c, response.ParamsValidError, "driver和filename不能为空")
		return
	}

	content, err := t.Srv.GetLuaFile(driver, filename)
	response.CheckAndRespWithData(c, map[string]string{"content": content}, err)
}

func (t *deviceType) saveLuaFile(c *gin.Context) {
	driver := c.Param("driver")
	filename := c.Param("filename")
	if driver == "" || filename == "" {
		response.FailWithMsg(c, response.ParamsValidError, "driver和filename不能为空")
		return
	}

	var reqBody struct {
		Content string `json:"content" binding:"required"`
	}
	if response.IsFailWithResp(c, util.VerifyUtil.Verify(c, &reqBody)) {
		return
	}

	err := t.Srv.SaveLuaFile(driver, filename, reqBody.Content)
	response.CheckAndResp(c, err)
}

func (t *deviceType) getDriverUsage(c *gin.Context) {
	driver := c.Param("driver")
	if driver == "" {
		response.FailWithMsg(c, response.ParamsValidError, "driver不能为空")
		return
	}

	names, count, err := t.Srv.GetDriverUsage(driver)
	response.CheckAndRespWithData(c, map[string]interface{}{
		"deviceTypes": names,
		"count":       count,
	}, err)
}

func (t *deviceType) listDrivers(c *gin.Context) {
	res, err := t.Srv.ListDrivers()
	response.CheckAndRespWithData(c, res, err)
}

func (t *deviceType) testProtocol(c *gin.Context) {
	driver := c.Param("driver")
	if driver == "" {
		response.FailWithMsg(c, response.ParamsValidError, "driver不能为空")
		return
	}

	var reqBody struct {
		MessageData string `json:"messageData" binding:"required"`
		Format      string `json:"format"`
	}
	if response.IsFailWithResp(c, util.VerifyUtil.Verify(c, &reqBody)) {
		return
	}

	// 默认格式为 hex
	if reqBody.Format == "" {
		reqBody.Format = "hex"
	}

	res, err := t.Srv.TestProtocol(driver, reqBody.MessageData, reqBody.Format)
	response.CheckAndRespWithData(c, res, err)
}
